package vg.services.user_interface_manager.additional_swing_components;

import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

/**
 * This class is bracket component.
 * @author tzolotuhin
 */
public class Bracket {
	private final JPanel view;
	private final JLabel display;
	private final JButton plusButton, minusButton;
	private final int type;
	// Mutex
	private final Object theMutex;
	//-------------------------------------------
	private int countBracket;//count of brackets
	private final static int DEF_MAX_BRACKET = 10;
	//-------------------------------------------
	public final static int DEF_LEFT_BRACKET = 1;
	public final static int DEF_RIGHT_BRACKET = 2;
	/**
	 * Constructor.
	 * @param type - type of bracket(left or right). You may use constants(DEF_LEFT_BRACKET and DEF_RIGTH_BRACKET).
	 * Note: count of brackets must be less 10.
	 */
	public Bracket(final int type) {
		this.type = type;
		this.countBracket = 0;
		this.display = new JLabel(" ");
		this.display.setFont(new Font("Consolas", Font.PLAIN, 24));
		this.plusButton = new JButton("+");
		this.theMutex = new Object();
		this.plusButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				synchronized (Bracket.this.theMutex) {
					if(Bracket.this.countBracket < DEF_MAX_BRACKET) {
						Bracket.this.countBracket++;
						Bracket.this.update();				
					}
				}
			}
		});
		this.minusButton = new JButton("-");
		this.minusButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				synchronized (Bracket.this.theMutex) {
					if(Bracket.this.countBracket > 0) {
						Bracket.this.countBracket--;
						Bracket.this.update();
					}
				}
			}
		});
		this.view = new JPanel(new GridBagLayout());
		//package all components of interface
		GridBagConstraints gbc = null;
		if(this.type == DEF_LEFT_BRACKET) {
			gbc = new GridBagConstraints(2,0,  1,1,  1,0,  GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0),  0,0);
			this.view.add(this.display, gbc);
			gbc = new GridBagConstraints(0,0,  1,1,  0,0,  GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0),  0,0);
			this.view.add(this.minusButton, gbc);
			gbc = new GridBagConstraints(1,0,  1,1,  0,0,  GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0),  0,0);			
			this.view.add(this.plusButton, gbc);
		} else {
			gbc = new GridBagConstraints(0,0,  1,1,  1,0,  GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0),  0,0);	
			this.view.add(this.display, gbc);
			gbc = new GridBagConstraints(1,0,  1,1,  0,0,  GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0),  0,0);
			this.view.add(this.minusButton, gbc);
			gbc = new GridBagConstraints(2,0,  1,1,  0,0,  GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0),  0,0);
			this.view.add(this.plusButton, gbc);
		}
		this.view.setVisible(true);
	}
	/**
	 * Returns view of this component.
	 */
	public JComponent getView() {
		return(this.view);
	}
	public String getText() {
		synchronized (this.theMutex) {
			return(this.display.getText());
		}
	}
	/**
	 * Update components
	 */
	private void update() {
		synchronized(Bracket.this.theMutex) {
			if(this.countBracket == 0) {
				this.display.setText(" ");
			} else {
				StringBuffer str = new StringBuffer(this.countBracket);
				for(int i = 0; i < this.countBracket; i++) {
					if(this.type == DEF_LEFT_BRACKET) {
						str.append("(");
					} else {
						str.append(")");
					}
				}
				this.display.setText(str.toString());
			}
		}
		SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				Bracket.this.view.updateUI();
			}
		});
	}
}
